/*
 * Copyright 2020-2021 redragon.dongbin
 *
 * This file is part of redragon-erp/赤龙ERP.

 * redragon-erp/赤龙ERP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.

 * redragon-erp/赤龙ERP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with redragon-erp/赤龙ERP.  If not, see <https://www.gnu.org/licenses/>.
 */
package com.erp.masterdata.material.service.spring;

import com.erp.dataset.dao.model.SysDataset;
import com.erp.dataset.dao.model.SysDatasetCO;
import com.erp.dataset.service.SysDatasetService;
import com.erp.masterdata.common.param.MasterDataParam;
import com.erp.masterdata.material.dao.MdMaterialDao;
import com.erp.masterdata.material.dao.model.MdMaterial;
import com.erp.masterdata.material.dao.model.MdMaterialCO;
import com.erp.masterdata.material.dao.model.MdMaterialCategory;
import com.erp.masterdata.material.service.MdMaterialCategoryService;
import com.erp.masterdata.material.service.MdMaterialService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.redragon.framework.hibernate.model.Pages;
import org.redragon.framework.util.EhcacheUtil;
import org.redragon.framework.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor=Exception.class)
public class MdMaterialServiceImpl implements MdMaterialService {

    //注入Dao
    @Autowired
    private MdMaterialDao mdMaterialDao;

    @Autowired
    private MdMaterialCategoryService materialCategoryService;

    @Autowired
    private SysDatasetService datasetService;

    @Override
    public void insertDataObject(MdMaterial obj) {
        this.mdMaterialDao.insertDataObject(obj);
        //清除缓存
        this.clearMdMaterialCache();
    }

    @Override
    public void updateDataObject(MdMaterial obj) {
        this.mdMaterialDao.updateDataObject(obj);
        //清除缓存
        this.clearMdMaterialCache();
    }
    
    @Override
    public void insertOrUpdateDataObject(MdMaterial obj) {
        this.mdMaterialDao.insertOrUpdateDataObject(obj);
        //清除缓存
        this.clearMdMaterialCache();
    }

    @Override
    public void deleteDataObject(MdMaterial obj) {
        this.mdMaterialDao.deleteDataObject(obj);
        //清除缓存
        this.clearMdMaterialCache();
    }

    @Override
    public List<MdMaterial> getDataObjects() {
        return this.mdMaterialDao.getDataObjects();
    }

    @Override
    public MdMaterial getDataObject(int id) {
        return this.mdMaterialDao.getDataObject(id);
    }

    @Override
    public MdMaterial getDataObject(String code) {
        return this.mdMaterialDao.getDataObject(code);
    }

    @Override
    public List<MdMaterial> getDataObjects(MdMaterialCO paramObj) {
        List<MdMaterial> mdMaterialList = this.mdMaterialDao.getDataObjects(paramObj);
        for(MdMaterial material : mdMaterialList){
            material.setCategoryDesc(materialCategoryService.getDataByCode(material.getCategoryCode()).getCategoryName());
        }
        return mdMaterialList;
    }

    @Override
    public List<MdMaterial> getDataObjects(Pages pages) {
        return this.mdMaterialDao.getDataObjects(pages);
    }
    
    @Override
    public List<MdMaterial> getDataObjects(Pages pages, MdMaterialCO paramObj) {
        return this.mdMaterialDao.getDataObjects(pages, paramObj);
    }
    
    @Override
    public List<Map<String, Object>> getDataObjectsArray(Pages pages, MdMaterialCO paramObj) {
        return this.mdMaterialDao.getDataObjectsArray(pages, paramObj);
    }
    
    @Override
    public List<MdMaterial> getDataObjectsForDataAuth(String dataAuthSQL, Pages pages, MdMaterialCO paramObj) {
        return this.mdMaterialDao.getDataObjectsForDataAuth(dataAuthSQL, pages, paramObj);
    }
    
    @Override
    public void updateApproveStatus(int id, String approveStatus) {
        this.mdMaterialDao.updateApproveStatus(id, approveStatus);
        //清除缓存
        this.clearMdMaterialCache();
    }
    
    //清理物料的所有缓存
    private void clearMdMaterialCache() {
        EhcacheUtil.clearCache(MasterDataParam.MATERIAL_CACHE_KEY);
        RedisUtil.clearCache(MasterDataParam.MATERIAL_CACHE_KEY);
        EhcacheUtil.clearCache(MasterDataParam.MATERIAL_MATERIAL_CACHE_KEY);
        RedisUtil.clearCache(MasterDataParam.MATERIAL_MATERIAL_CACHE_KEY);
        EhcacheUtil.clearCache(MasterDataParam.MATERIAL_MATTER_CACHE_KEY);
        RedisUtil.clearCache(MasterDataParam.MATERIAL_MATTER_CACHE_KEY);
        
        EhcacheUtil.clearCacheBatch("*getMdMaterialInfoCache*");
        RedisUtil.clearCacheBatch("*getMdMaterialInfoCache*");
    }


    @Override
    public List<MdMaterial> excelEmportFile(List<ArrayList<String>> readExcel, String fileName, String postfix) {
        // 读取数据封装实体
        if(readExcel.size() == 0) {
            return null;
        }
        List<MdMaterial> materialList = getCustorList(readExcel);
        List<MdMaterial> newDoList = new ArrayList<>();
        for(MdMaterial material : materialList) {
            //判断该条数据在新的集合中是否存在
            if(StringUtils.isEmpty(material.getMaterialType())){
                material.setErrSource("物料/服务不能为空！");
                newDoList.add(material);
                continue;
            }
            if(StringUtils.isEmpty(material.getMaterialCode())){
                material.setErrSource("物料/服务编码不能为空！");
                newDoList.add(material);
                continue;
            }
            MdMaterial oldMaterial = mdMaterialDao.getDataByCode(material.getMaterialCode());
            if(ObjectUtils.isNotEmpty(oldMaterial)){
                material.setErrSource("物料/服务编码已存在！");
                newDoList.add(material);
                continue;
            }
            if(StringUtils.isEmpty(material.getMaterialName())){
                material.setErrSource("物料/服务名称不能为空！");
                newDoList.add(material);
                continue;
            }
            if(StringUtils.isEmpty(material.getCategoryCode())){
                material.setErrSource("物料/服务类别不能为空或为找到对应的类别！");
                newDoList.add(material);
                continue;
            }
            if(StringUtils.isEmpty(material.getMaterialUnit())){
                material.setErrSource("单位不能为空或为找到对应的单位！");
                newDoList.add(material);
                continue;
            }
            material.setIsDel(MasterDataParam.IS_DEL_NO);
            mdMaterialDao.insertDataObject(material);
        }
        return newDoList;
//        //将异常数据返回回去
//        //**根据文件的后缀名选择执行方法整理excel文件**
//        if(!ExcelUtils.EMPTY.equals(postfix)){
//            if(ExcelUtils.OFFICE_EXCEL_2003_POSTFIX.equals(postfix)){
//                return exportXLSExcel(newDoList, fileName);
//            }else if(ExcelUtils.OFFICE_EXCEL_2010_POSTFIX.equals(postfix)){
//                return exportXLSXExcel(newDoList, fileName);
//            }
//        }
//        return null;
    }

    /*
     * 将读取的excel文件内容封装
     */
    public List<MdMaterial> getCustorList(List<ArrayList<String>> readExcel){
        //获取单位数据
        SysDatasetCO datasetCO = new SysDatasetCO();
        datasetCO.setDatasetTypeCode("material_unit");
        datasetCO.setStatus(MasterDataParam.MATERIAL_STATUS_Y);
        List<SysDataset> datasets = datasetService.getDataObjects(datasetCO);
        List<MdMaterial> doList = new ArrayList<>();
        for(List<String> sList : readExcel) {
            MdMaterial material = new MdMaterial();
            int count = 0;
            for(String str : sList) {
                if(0 == count) {
                    // 物料/服务
                    if(MasterDataParam.MATERIAL_TYPE_NAME.equals(str.toString().trim())){
                        material.setMaterialType(str==null?"":MasterDataParam.MATERIAL_TYPE);
                    }else if(MasterDataParam.MATTER_TYPE_NAME.equals(str.toString().trim())){
                        material.setMaterialType(str==null?"":MasterDataParam.MATTER_TYPE);
                    }
                }else if(1 == count) {
                    //物料/服务编码
                    material.setMaterialCode(str==null?"":str.toString().trim());
                }else if(2 == count) {
                    //物料/服务名称
                    material.setMaterialName(str==null?"":str.toString().trim());
                }else if(3 == count) {
                    //物料/服务类别
                    MdMaterialCategory category = materialCategoryService.getDataByName(str.toString());
                    material.setCategoryCode(ObjectUtils.isEmpty(category)?"":category.getCategoryCode());
                }else if(4 == count) {
                    //规格型号
                    material.setStandard(str==null?"":str.toString());
                }else if(5 == count) {
                    //品牌
                    material.setBrand(str==null?"":str.toString().trim());
                }else if(6 == count) {
                    //单位
                    for(SysDataset dataset : datasets){
                        if(dataset.getDatasetName().equals(str.toString().trim())){
                            material.setMaterialUnit(str==null?"":dataset.getDatasetCode());
                            break;
                        }
                    }
                }else if(7 == count) {
                    //供应商
                    material.setSupplier(str==null?"":str.toString().trim());
                }else if(8 == count) {
                    //状态
                    if("有效".equals(str.toString().trim())){
                        material.setStatus(str==null?"":MasterDataParam.MATERIAL_STATUS_Y);
                    }else if("停用".equals(str.toString().trim())){
                        material.setStatus(str==null?"":MasterDataParam.MATERIAL_STATUS_N);
                    }
                }else if(9 == count) {
                    //备注
                    material.setRemark(str==null?"":str.toString());
                }
                count ++;
            }
            doList.add(material);
        }
        return doList;
    }

    public Workbook exportXLSExcel(List<MdMaterial> doList,String fileName) {
        // 创建Excel表。
        Workbook book = new HSSFWorkbook();
        // 在当前Excel创建一个子表
        Sheet sheet = book.createSheet("DIS"+fileName);
        // 设置表头信息（写入Excel左上角是从(0,0)开始的）
        Row row = sheet.createRow(0);
        row.createCell(0).setCellValue("物料/服务编码");
        row.createCell(1).setCellValue("物料/服务名称");
        row.createCell(2).setCellValue("错误原因");
        int count = 1;
        for(MdMaterial material : doList) {
            // 行
            Row rows = sheet.createRow(count);
            // 单元格
            // 写入数据
            rows.createCell(0).setCellValue(material.getMaterialCode());
            rows.createCell(1).setCellValue(material.getMaterialName());
            rows.createCell(2).setCellValue(material.getErrSource());
            count ++;
        }
        // 保存excel文件
        /*try {
			book.write(new FileOutputStream("D://Excel//" + "DIS"+fileName + ".xls"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} */
        return book;
    }

    public Workbook exportXLSXExcel(List<MdMaterial> doList,String fileName) {
        // 创建Excel表。
        Workbook book = new XSSFWorkbook();
        // 在当前Excel创建一个子表
        Sheet sheet = book.createSheet("DIS"+fileName);
        // 设置表头信息（写入Excel左上角是从(0,0)开始的）
        Row row = sheet.createRow(0);
        row.createCell(0).setCellValue("物料/服务编码");
        row.createCell(1).setCellValue("物料/服务名称");
        row.createCell(2).setCellValue("错误原因");

        int count = 1;
        for(MdMaterial material : doList) {
            // 行
            Row rows = sheet.createRow(count);
            // 单元格
            // 写入数据
            rows.createCell(0).setCellValue(material.getMaterialCode());
            rows.createCell(1).setCellValue(material.getMaterialName());
            rows.createCell(2).setCellValue(material.getErrSource());
            count ++;
        }

        return book;
    }

    @Override
    public String getNewMaterialCodeByCategory(String categoryCode) {
        return mdMaterialDao.getMaterialDataByCode(categoryCode);
    }

    @Override
    public MdMaterial getDataByCode(String materialCode){
        return mdMaterialDao.getDataByCode(materialCode);
    }
}